/*******************************************************************************
 * This header file contains all the classes of the Syntax analyzer.
 *
 * Syntax analyzer is the second process of sbasic language interpreter
 *
 * Contains the syntax processor.
 * 
 * By using syntax processor, you can get a Abstract syntax tree(AST for short).
 *
 * @author LoveLonelyTime
 * @version 1.1
 * @date 2021-2021
 * @copyright GNU Public License.
 ******************************************************************************/

#ifndef ANALYZER_H_INCLUDED
#define ANALYZER_H_INCLUDED

#include <string>
#include <vector>

#include "lexer.h"

namespace SBASIC
{
    /**
     * SyntaxAnalyer Class.
     * A syntax processor implement.
     */
    class SyntaxAnalyer
    {
    private:
        /**
         * Used TokenReader.
         */
        TokenReader &m_token_reader;

        /**
         * The current Token.
         */
        Token *m_token_ptr;

        /**
         * Read a token.
         */
        void read_token();

        void stmts(std::vector<Stmt *> &stmt_vector);
        void exps(std::vector<Expression *> &exp_vector);
        void exp_tail(std::vector<Expression *> &exp_vector);
        Stmt *stmt();
        std::string *prompt();
        void ids(std::vector<VariableExpression *> &vars_vector);
        void id_Tail(std::vector<VariableExpression *> &vars_vector);
        Expression *exp();
        Expression *primary_exp();
        void param(std::vector<Expression *> &exp_vector);
        void args(std::vector<Expression *> &exp_vector);
        void arg_tail(std::vector<Expression *> &exp_vector);
        Expression *unary_exp();
        Expression *power_exp();
        TailExpression *power_exp_tail();
        Expression *mult_exp();
        TailExpression *mult_exp_tail();
        Expression *mod_exp();
        TailExpression *mod_exp_tail();
        Expression *add_exp();
        TailExpression *add_exp_tail();
        Expression *relationship_exp();
        TailExpression *relationship_exp_tail();
        Expression *or_exp();
        TailExpression *or_exp_tail();

    public:
        /**
         * Create a SyntaxAnalyer by TokenReader.
         * @param[in] token_reader The TokenReader.
         */
        SyntaxAnalyer(TokenReader &token_reader);

        /**
         * Handle all tokens to get an AST.
         */
        Program *analyer();

        /**
         * Free the AST.
         * @param[in] program The pointer of AST.
         */
        void delete_program(Program *program)
        {
            delete program;
        }
        ~SyntaxAnalyer();
    };
}

#endif // ANALYZER_H_INCLUDED
